/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.hutech09.jsale.bsn.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import org.hutech09.jsale.bsn.IProductManager;
import org.hutech09.jsale.bsn.common.DataExistsException;
import org.hutech09.jsale.bsn.common.DataNotExistedException;
import org.hutech09.jsale.bsn.common.IGenericDao;
import org.hutech09.jsale.bsn.exception.ItemNotFoundException;
import org.hutech09.jsale.entity.InfoType;
import org.hutech09.jsale.entity.Price;
import org.hutech09.jsale.entity.Product;
import org.hutech09.jsale.entity.ProductDetail;
import org.hutech09.jsale.entity.ProductImage;

/**
 *
 * @author Nam
 */
@Stateless
public class ProductManager implements IProductManager {

    private static final Logger LOG = Logger.getLogger(ProductManager.class.getName());

    @EJB
    private IGenericDao dao;

    @Override
    public long countProduct() {
        return dao.count(Product.class);
    }

    @Override
    public long countProduct(Map<String, Object> filter) {
        return dao.count(Product.class, filter);
    }

    @Override
    public List<Product> findProductPage(int firstIndex, int pageSize, String orderField, boolean desc, Map<String, Object> filter) {
        return dao.findPaging(Product.class, firstIndex, pageSize, orderField, desc, filter);
    }

    @Override
    public Product findProductById(long id) {
        return dao.find(Product.class, id);
    }

    @Override
    public List<Price> getPrices(long productId) throws ItemNotFoundException {
        Product pro = dao.find(Product.class, productId);
        if (pro == null) {
            throw new ItemNotFoundException(new Product(productId));
        }
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("product", pro);
        return dao.findByNamedQuery("Price.findByProduct", params);
    }

    @Override
    public Price addPrice(Price price) {
        try {
            return dao.create(price);
        } catch (DataExistsException ex) {
            Logger.getLogger(ProductManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    @Override
    public void updatePrice(Price price) throws ItemNotFoundException {
        try {
            dao.update(price);
        } catch (DataNotExistedException ex) {
            throw new ItemNotFoundException(price);
        }
    }

    @Override
    public void deletePrice(long priceId) throws ItemNotFoundException {
        try {
            dao.delete(Price.class, priceId);
        } catch (DataNotExistedException ex) {
            throw new ItemNotFoundException(new Price(priceId));
        }
    }

    @Override
    public Product create(Product pro) {
        if (pro == null) {
            throw new IllegalArgumentException("product can't be null");
        }
        if (pro.getId() != null) {
            throw new IllegalArgumentException("Product.id must be null");
        }
        try {
            return dao.create(pro);
        } catch (DataExistsException ex) {
            LOG.warning("Create product error: " + pro);
        }
        return null;
    }

    @Override
    public ProductImage addImage(ProductImage image) {
        try {
            return dao.create(image);
        } catch (DataExistsException ex) {
            Logger.getLogger(ProductManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public List<String> getImagePaths(long productId) throws ItemNotFoundException {
        Product pro = dao.find(Product.class, productId);
        if (pro == null) {
            throw new ItemNotFoundException(new Product(productId));
        }
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("product", pro);
        List<ProductImage> productImages = dao.findByNamedQuery("ProductImage.findByProduct", params);

        List<String> imagePaths = new ArrayList<String>();
        for (ProductImage image : productImages) {
            imagePaths.add(image.getImagePath());
        }
        return imagePaths;
    }

    public ProductImage updateImage(ProductImage image) throws ItemNotFoundException {
        try {
            return dao.update(image);
        } catch (DataNotExistedException ex) {
            throw new ItemNotFoundException(image);
        }
    }

    @Override
    public void update(Product pro) throws ItemNotFoundException {
        try {
            dao.update(pro);
        } catch (DataNotExistedException ex) {
            throw new ItemNotFoundException(pro);
        }
    }

    @Override
    public List<ProductDetail> getDetail(long productId) throws ItemNotFoundException {
        Product pro = dao.find(Product.class, productId);
        if (pro == null) {
            throw new ItemNotFoundException(new Product(productId));
        }
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("product", pro);
        return dao.findByNamedQuery("ProductDetail.findByProduct", params);
    }

    @Override
    public void deleteImage(long imageId) throws ItemNotFoundException {
        try {
            dao.delete(ProductImage.class, imageId);
        } catch (DataNotExistedException ex) {
            throw new ItemNotFoundException(new ProductImage(imageId));
        }
    }

    @Override
    public ProductDetail addDetail(ProductDetail detail) {
        if (detail == null) {
            throw new IllegalArgumentException("productDetail can't be null.");
        }
        if (detail.getInfoType() == null || detail.getProduct() == null) {
            throw new IllegalArgumentException("productDetail.infoType and productDetail.product can't be null");
        }
        try {
            return dao.create(detail);
        } catch (DataExistsException ex) {
            Logger.getLogger(ProductManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    @Override
    public void deleteProductDetail(ProductDetail detail) throws ItemNotFoundException {
        if (detail == null) {
            throw new IllegalArgumentException("productDetail can't be null.");
        }
        try {
            dao.delete(detail);
        } catch (DataNotExistedException ex) {
            Logger.getLogger(ProductManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public List<ProductImage> getProductImages(long productId) throws ItemNotFoundException {
        Product pro = dao.find(Product.class, productId);
        if (pro == null) {
            throw new ItemNotFoundException(new Product(productId));
        }
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("product", pro);
        return dao.findByNamedQuery("ProductImage.findByProduct", params);
    }

    @Override
    public List<Price> findPricePage(int firstIndex, int pageSize, String orderField, boolean desc, Map<String, Object> filter) {
        return dao.findPaging(Price.class, firstIndex, pageSize, orderField, desc, filter);
    }

    @Override
    public long countPrice(Map<String, Object> filter) {
        return dao.count(Price.class, filter);
    }

    @Override
    public Price findPriceById(long priceId) {
        return dao.find(Price.class, priceId);
    }

    @Override
    public InfoType getInfoType(long id) {
        return dao.find(InfoType.class, id);
    }

    @Override
    public InfoType createInfoType(InfoType infoType) {
        if (infoType == null) {
            throw new IllegalArgumentException("infoType can't be null.");
        }
        if (infoType.getId() != null) {
            throw new IllegalArgumentException("infoType.id must be null.");
        }
        try {
            return dao.create(infoType);
        } catch (DataExistsException ex) {
            Logger.getLogger(ProductManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    @Override
    public void updateInfoType(InfoType infoType) {
        if (infoType == null) {
            throw new IllegalArgumentException("infoType can't be null.");
        }
        if (infoType.getId() != null) {
            throw new IllegalArgumentException("infoType.id can't be null.");
        }
        try {
            dao.update(infoType);
        } catch (DataNotExistedException ex) {
            Logger.getLogger(ProductManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public List<InfoType> getAllInfoType() {
        return dao.getAll(InfoType.class);
    }

    @Override
    public void deleteInfoType(long id) throws ItemNotFoundException {
        try {
            dao.delete(InfoType.class, id);
        } catch (DataNotExistedException ex) {
            throw new ItemNotFoundException(new InfoType(id));
        }
    }

    @Override
    public List<InfoType> findListInfoType(String name) {
        Map<String, Object> filter = new HashMap<String, Object>();
        filter.put("name", name);
        return dao.findPaging(InfoType.class, 0, 10, "name", true, filter);
    }

    @Override
    public InfoType findInfoType(String name) {
        Map<String, String> params = new HashMap();
        params.put("name", name);
        List<InfoType> types = dao.findByNamedQuery("InfoType.findByName", params);
        if (types != null && !types.isEmpty()) {
            return types.get(0);
        }
        return null;
    }

    @Override
    public void updateProductDetail(ProductDetail detail) throws ItemNotFoundException {
        try {
            dao.update(detail);
        } catch (DataNotExistedException ex) {
            throw new ItemNotFoundException(detail);
        }
    }

    @Override
    public List<Product> findProductByName(String name) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("name", name);
        int c = (int) countProduct(map);
        return findProductPage(0, c, null, true, map);
    }

    @Override
    public List<Product> getNewProduct() {
        return dao.findPaging(Product.class, 0, 10, "createdDate", true);
    }
}
